# -*- coding: utf-8 -*-
import json
import os
import sseclient
import requests
import session
import time


from pathlib import Path
from tencentcloud.common.common_client import CommonClient
from tencentcloud.common import credential
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile
from qcloud_cos import CosConfig
from qcloud_cos import CosS3Client

def offlineUpateFile(filePath: str):
    EndPoint        = "lke.tencentcloudapi.com"
    SecretID        = "**********"
    SecretKey       = "**********"
    BotBizID        = "**********"
    TypeKeyRealtime = "realtime" # 实时文件上传类型
    TypeKeyOffline  = "offline"  # 离线文档上传类型
    Region          = "ap-guangzhou"


    #filePath = "./requirements.txt"
    fileName = Path(filePath).name
    fileExt = Path(filePath).suffix[1:]
    print("filePath: ",filePath)
    print("fileName: ",fileName)
    print("fileExt: ",fileExt)



    ######## step 1 获取临时密钥 ###########
    try:
        cred = credential.Credential(SecretID, SecretKey)
        httpProfile = HttpProfile()
        httpProfile.endpoint = EndPoint
        clientProfile = ClientProfile()
        clientProfile.httpProfile = httpProfile

        # 请注意，此处为离线文档上传，TypeKey取值为offline;
        # 如果需要复用此处代码上传实时文档，需要修改TypeKey取值为 realtime
        params = {
            "BotBizId": BotBizID,
            "FileType": fileExt,
            "IsPublic": False,
            "TypeKey": TypeKeyOffline

        }
        common_client = CommonClient("lke", "2023-11-30", cred, Region, profile=clientProfile)
        resp = common_client.call_json("DescribeStorageCredential", params)
        tmpSecretId = resp['Response']['Credentials']['TmpSecretId']
        tmpSecretKey = resp['Response']['Credentials']['TmpSecretKey']
        tmpToken = resp['Response']['Credentials']['Token']
        uploadPath = resp['Response']['UploadPath']
        bucket = resp['Response']['Bucket']
        region = resp['Response']['Region']

        print("======== DescribeStorageCredential Success =======")
        print("tmpSecretId: ", tmpSecretId)
        print("tmpSecretKey: ", tmpSecretKey)
        print("tmpToken: ", tmpToken)
        print("uploadPath: ", uploadPath)
        print("bucket: ", bucket)
        print("region: ", region)
    except TencentCloudSDKException as err:
        print(err)
        return False



    print("======= 获取临时密钥成功 =============\n\n")


    ######## step 2 上传文档到知识引擎的cos ###########
    # 参考：https://cloud.tencent.com/document/product/436/14113
    config = CosConfig(Region=region, SecretId=tmpSecretId, SecretKey=tmpSecretKey, Token=tmpToken, Scheme='https')
    client = CosS3Client(config)
    # 使用高级接口上传一次，不重试，此时没有使用断点续传的功能
    response = client.upload_file(
        Bucket=bucket,
        Key=uploadPath,
        LocalFilePath=fileName,
        EnableMD5=False,
        progress_callback=None
    )

    print('上传后结果:' + str(response))
    rsp = response
    eTag = rsp.get('ETag')
    cosHash = rsp.get('x-cos-hash-crc64ecma')
    print('etag: ' + eTag)
    print('coshash: ' + cosHash)
    print(" \n\n ============== \n\n")


    ######### step 3 从cos转存到知识引擎 ###########
    try:
        params = {
            "BotBizId": BotBizID,
            "FileName": fileName,
            "FileType": fileExt,
            "CosUrl": uploadPath,
            "ETag": eTag,
            "CosHash": cosHash,
            "Size": str(os.path.getsize(fileName)),
            "AttrRange": 1
        }

        cred = credential.Credential(SecretID, SecretKey)

        httpProfile = HttpProfile()
        httpProfile.endpoint = EndPoint
        clientProfile = ClientProfile()
        clientProfile.httpProfile = httpProfile
        common_client = CommonClient("lke", "2023-11-30", cred, Region, profile=clientProfile)
        resp = common_client.call_json("SaveDoc", params)
    except TencentCloudSDKException as err:
        print(err)
        return False

    ############ step 4 轮询文档状态 ###########
    try:
        flag = False
        params = {
            "BotBizId": BotBizID,
            "PageNumber": 1,
            "PageSize": 10
        }
        while flag == False :
            cred = credential.Credential(SecretID, SecretKey)
            httpProfile = HttpProfile()
            httpProfile.endpoint = EndPoint
            clientProfile = ClientProfile()
            clientProfile.httpProfile = httpProfile
            common_client = CommonClient("lke", "2023-11-30", cred, Region, profile=clientProfile)
            resp = common_client.call_json("ListDoc", params)
            # print(resp)
            docList = resp['Response']['List'] 
            for mlist in docList:
                if (mlist['FileName'] and mlist['Status'] == 10):
                    flag = True
                    print(mlist['FileName'] + " -> " + mlist['StatusDesc'])
                    break
                # print(mlist['Status'])
    except TencentCloudSDKException as err:
        print(err)
        return False
        
    ########## step 5 发布 #########

    try:
        params = {
            "BotBizId": BotBizID
        }

        cred = credential.Credential(SecretID, SecretKey)

        httpProfile = HttpProfile()
        httpProfile.endpoint = EndPoint
        clientProfile = ClientProfile()
        clientProfile.httpProfile = httpProfile
        common_client = CommonClient("lke", "2023-11-30", cred, Region, profile=clientProfile)
        resp = common_client.call_json("CreateRelease", params)
    except TencentCloudSDKException as err:
        print(err)
        return False
    
    '''    
    ########## step 6 检查发布状态 ##########
    try:
        flag = False
        params = {
            "BotBizId": BotBizID
        }
        while flag == False :
            cred = credential.Credential(SecretID, SecretKey)
            httpProfile = HttpProfile()
            httpProfile.endpoint = EndPoint
            clientProfile = ClientProfile()
            clientProfile.httpProfile = httpProfile
            common_client = CommonClient("lke", "2023-11-30", cred, Region, profile=clientProfile)
            resp = common_client.call_json("DescribeReleaseInfo", params)
            print(resp)
            reStatus = resp['Response']['Status'] 
            #if (reStatus == 3):
            #    break
    except TencentCloudSDKException as err:
        print(err)
        
    ''' 
    return True


def sse_client(sid: str):
    bot_app_key = "********"  # 机器人密钥，不是BotBizId (从运营接口人处获取)
    visitor_biz_id = "202503020001"  # 访客 ID（外部系统提供，需确认不同的访客使用不同的 ID）
    streaming_throttle = 1  # 节流控制
    req_data = {
        "content": "",
        "bot_app_key": bot_app_key,
        "visitor_biz_id": visitor_biz_id,
        "session_id": sid,
        "streaming_throttle": streaming_throttle
    }
    try:
        while True:
            content = input("请输入你想问的问题：")
            if content == "exit":
                exit(0)
            req_data["content"] = content
            print("req_data:")
            #print(req_data)
            # print(f'req_data:{req_data}')
            resp = requests.post("https://wss.lke.cloud.tencent.com/v1/qbot/chat/sse", data=json.dumps(req_data),
                                 stream=True, headers={"Accept": "text/event-stream"})
            print("resp:")
            #print(f"resp:{resp.text}")
            client = sseclient.SSEClient(resp)
            print("Client:")
            for ev in client.events():
                print(f'event:{ev.event}, "data:"{ev.data}')
                data = json.loads(ev.data)
                if ev.event == "reply":
                    if data["payload"]["is_from_self"]:  # 自己发出的包
                        print(f'is_from_self, event:{ev.event}, "content:"{data["payload"]["content"]}')
                    elif data["payload"]["is_final"]:  # 服务端event传输完毕；服务端的回复是流式的，最后一条回复的content，包含完整内容
                        print(f'is_final, event:{ev.event}, "content:"{data["payload"]["content"]}')
                else:
                    print(f'event:{ev.event}, "data:"{ev.data}')
    except Exception as e:
        print(e)

if __name__ == "__main__":
    content = input("请输入你要上传的新文件路径（输入 q 可跳过此步骤）：")
    if content != "q" :
        if (offlineUpateFile(content)):
            print("等待发布成功......")
            time.sleep(5) # 休眠5秒
    session_id = session.get_session()
    sse_client(session_id)
